package com.tanger.pay.wechat;

import com.tanger.common.utils.MD5Util;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.security.SecureRandom;
import java.util.*;

/**
 * @Description 支付工具类
 * @Author Hchenbin
 * @Date 2024-01-04 17:13
 * @Version 1.0
 */

public class WeChatUtil {

    private static final String SYMBOLS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";

    private static final Random RANDOM = new SecureRandom();

    /**
     * @Description 微信签名
     */
    public static String sign(Map<String, String> params) {
        //第一步,排序
        String paramsStr = paramAsciiSort(params);
        //第二步,拼接密钥
        String key = WeChatPayConfig.key;
        paramsStr = paramsStr + "&key=" + key;
        //第三步,MD5加密(我这里默认)
        String sign = MD5Util.encode(paramsStr).toUpperCase();
        return sign;
    }

    /**
     * @Description: 参数按照key=value的格式,并按照参数吗ASCII字典排序
     */
    public static String paramAsciiSort(Map<String, String> params) {
        List<String> keys = new ArrayList<String>(params.keySet());
        Collections.sort(keys);
        String sortStr = "";
        for (int i = 0; i < keys.size(); i++) {
            String key = keys.get(i);
            String value = params.get(key);
            if (i == keys.size() - 1) {// 拼接时，不包括最后一个&字符
                sortStr = sortStr + key + "=" + value;
            } else {
                sortStr = sortStr + key + "=" + value + "&";
            }
        }
        return sortStr;
    }

    /**
     * @Description: 去除空值和sign
     */
    public static Map<String, String> paramsFilterSign(Map<String, String> params) {
        Map<String, String> result = new HashMap<String, String>();
        if (params == null || params.size() <= 0) {
            return result;
        }
        for (String key : params.keySet()) {
            String value = params.get(key);
            if (value == null || "".equals(value) || "sign".equalsIgnoreCase(key) || "sign_type".equalsIgnoreCase(key)) {
                continue;
            }
            result.put(key, value);
        }
        return result;
    }

    /**
     * 判断签名是否正确
     *
     * @param xmlStr XML格式数据
     * @return 签名是否正确
     * @throws Exception
     */
    public static boolean signValid(String xmlStr) throws Exception {
        Map<String, String> data = MapXmlUtil.xml2Map(xmlStr);
        if (!data.containsKey("sign")) {
            return false;
        }
        String sign = data.get("sign");

        return sign(data).equals(sign);
    }

    /**
     * 获取本机Ip地址
     * @return
     */
    public static String getLocalIp(){
        try {
            InetAddress addr = InetAddress.getLocalHost();
            //获取本机ip
            return addr.getHostAddress();
        } catch (UnknownHostException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 获取随机字符串 Nonce Str
     *
     * @return String 随机字符串
     */
    public static String randomStr() {
        char[] nonceChars = new char[32];
        for (int index = 0; index < nonceChars.length; ++index) {
            nonceChars[index] = SYMBOLS.charAt(RANDOM.nextInt(SYMBOLS.length()));
        }
        return new String(nonceChars);
    }

    /**
     * 支付金额单位:元转分 （12.23元 >>> 1223分）
     * @param amount
     * @return
     */
    public static String changeY2F(String amount) {
        String currency = amount.replaceAll("\\$|\\￥|\\,", "");
        // 或者$的金额
        int index = currency.indexOf(".");
        int length = currency.length();
        Long amLong = 0l;
        if (index == -1) {
            amLong = Long.valueOf(currency + "00");
        } else if (length - index >= 3) {
            amLong = Long.valueOf((currency.substring(0, index + 3)).replace(".", ""));
        } else if (length - index == 2) {
            amLong = Long.valueOf((currency.substring(0, index + 2)).replace(".", "") + 0);
        } else {
            amLong = Long.valueOf((currency.substring(0, index + 1)).replace(".", "") + "00");
        }
        return amLong.toString();
    }
}
